/*
 * M2Bomb.java
 * 
 * author: The MomberBan Team 
 * date: 15.09.2008
 */

package at.momberban2.me.gamecontext;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Layer;
import javax.microedition.lcdui.game.Sprite;

import de.enough.polish.io.Externalizable;

import at.momberban2.me.game.M2ResourceManager;

/**
 * @author patchinsky
 */
public class M2Bomb implements Externalizable {
    private static transient final M2ResourceManager MGR = (M2ResourceManager) M2ResourceManager
            .getInstance();

    /**
     * the bomb width
     */
    public static final byte BOMB_WIDTH = 32;

    /**
     * the bomb height
     */
    public static final byte BOMB_HEIGHT = 32;

    /**
     * define the trigger delay (msec)
     */
    public static final long TRIGGER_DELAY = Long.parseLong(MGR
            .getCfgFor("triggerDelay"));

    /**
     * get the default explosion range
     */
    public static final byte DEFAULT_EXPLOSION_RANGE = Byte.parseByte(MGR
            .getCfgFor("explosionRange"));

    private static final Image IMAGE_BOMB = MGR.loadImage("/images/Bomb.png");

    private static final Image IMAGE_EXPLOSION = MGR
            .loadImage("/images/Explosion.png");

    private static Image IMAGE_UP = null;

    private static Image IMAGE_LEFT = null;

    private static Image IMAGE_RIGHT = null;

    private static Image IMAGE_DOWN = null;

    private Sprite sprite;

    private M2Player player;

    private int positionId;

    private long timePlanted;

    private boolean isTriggered;

    private short explosionRange = DEFAULT_EXPLOSION_RANGE;

    static {
        IMAGE_RIGHT = Image.createImage(IMAGE_EXPLOSION, 0, 0, IMAGE_EXPLOSION
                .getWidth(), IMAGE_EXPLOSION.getHeight(), Sprite.TRANS_NONE);
        IMAGE_LEFT = Image.createImage(IMAGE_EXPLOSION, 0, 0, IMAGE_EXPLOSION
                .getWidth(), IMAGE_EXPLOSION.getHeight(), Sprite.TRANS_ROT180);
        IMAGE_DOWN = Image.createImage(IMAGE_EXPLOSION, 0, 0, IMAGE_EXPLOSION
                .getWidth(), IMAGE_EXPLOSION.getHeight(), Sprite.TRANS_ROT90);
        IMAGE_UP = Image.createImage(IMAGE_EXPLOSION, 0, 0, IMAGE_EXPLOSION
                .getWidth(), IMAGE_EXPLOSION.getHeight(), Sprite.TRANS_ROT270);
    }

    /**
     * constructor
     * 
     * @deprecated
     */
    public M2Bomb() {
        // Media.playBombSound();
        // only used in serialization
        this.sprite = new Sprite(IMAGE_BOMB, BOMB_WIDTH, BOMB_HEIGHT);
    }
    
    /**
     * constructor
     * 
     * @param player
     * @param x 
     * @param y 
     * @param timePlanted
     * @param range 
     */
    public M2Bomb(M2Player player, int x, int y, long timePlanted, short range) {
        this.player = player;
        this.timePlanted = timePlanted;
        this.explosionRange = range;
        this.sprite = new Sprite(IMAGE_BOMB, BOMB_WIDTH, BOMB_HEIGHT);
        this.sprite.setPosition(x, y);
    }

    /**
     * let it explode
     * 
     * @return a sprite array
     * @throws IOException
     */
    public Sprite[] explode() {
        // Logger.log("bomb explode");

        Vector sprites = new Vector();
        Sprite middle = new Sprite(IMAGE_EXPLOSION,
                IMAGE_EXPLOSION.getWidth() / 3, IMAGE_EXPLOSION.getHeight());

        // original bomb position
        int bX = this.sprite.getX();
        int bY = this.sprite.getY();

        middle.setPosition(bX, bY);
        middle.setFrame(1);
        sprites.addElement(middle);
        // Logger.log("UP = " + Canvas.UP + " DOWN = " + Canvas.DOWN + " LEFT =
        // " + Canvas.LEFT + " RIGHT = " + Canvas.RIGHT);
        for (int i = 1; i <= this.explosionRange; i++) {
            int j = Canvas.UP;
            do {
                Sprite s = null;
                // Logger.log("Explosion-sprite: Distance to middle: " + i + ";
                // Direction: " + j);
                if (j == Canvas.UP) {
                    s = new Sprite(IMAGE_UP, IMAGE_EXPLOSION.getWidth() / 3,
                            IMAGE_EXPLOSION.getHeight());
                    s.setPosition(bX, bY - s.getHeight() * i);
                    j = Canvas.RIGHT;
                    if (i == this.explosionRange) {
                        s.setFrame(0);
                    } else {
                        s.setFrame(2);
                    }
                } else if (j == Canvas.RIGHT) {
                    s = new Sprite(IMAGE_RIGHT, IMAGE_EXPLOSION.getWidth() / 3,
                            IMAGE_EXPLOSION.getHeight());
                    s.setPosition(bX + s.getWidth() * i, bY);
                    if (i == this.explosionRange) {
                        s.setFrame(2);
                    } else {
                        s.setFrame(0);
                    }
                    j = Canvas.DOWN;
                } else if (j == Canvas.DOWN) {
                    s = new Sprite(IMAGE_DOWN, IMAGE_EXPLOSION.getWidth() / 3,
                            IMAGE_EXPLOSION.getHeight());
                    s.setPosition(bX, bY + s.getHeight() * i);
                    if (i == this.explosionRange) {
                        s.setFrame(2);
                    } else {
                        s.setFrame(0);
                    }
                    j = Canvas.LEFT;
                } else if (j == Canvas.LEFT) {
                    s = new Sprite(IMAGE_LEFT, IMAGE_EXPLOSION.getWidth() / 3,
                            IMAGE_EXPLOSION.getHeight());
                    s.setPosition(bX - s.getWidth() * i, bY);
                    if (i == this.explosionRange) {
                        s.setFrame(0);
                    } else {
                        s.setFrame(2);
                    }
                    j = Canvas.UP;
                }
                sprites.addElement(s);
            } while (j != Canvas.UP);
        }
        Sprite[] result = new Sprite[sprites.size()];
        sprites.copyInto(result);
        return result;
    }

    /**
     * @param positionId
     *            to set
     */
    public void setPositionId(int positionId) {
        this.positionId = positionId;
    }

    /**
     * @return positionId
     */
    public int getPositionId() {
        return positionId;
    }

    /**
     * Getter of the property <tt>player</tt>
     * 
     * @return Returns the player.
     */

    public M2Player getPlayer() {
        return player;
    }

    /**
     * Setter of the property <tt>player</tt>
     * 
     * @param player
     *            The player to set.
     */
    public void setPlayer(M2Player player) {
        this.player = player;
    }

    /**
     * Getter of the property <tt>timePlanted</tt>
     * 
     * @return Returns the timePlanted.
     */

    public long getTimePlanted() {
        return timePlanted;
    }

    /**
     * Setter of the property <tt>timePlanted</tt>
     * 
     * @param timePlanted
     *            The timePlanted to set.
     */
    public void setTimePlanted(long timePlanted) {
        this.timePlanted = timePlanted;
    }

    /**
     * @param now 
     * @return
     */
    public boolean isTriggered(long now) {
        return isTriggered || (now - timePlanted > TRIGGER_DELAY);
    }

    /**
     * trigger the bomb
     * 
     * @param isTriggered
     *            to set
     */
    public void trigger() {
        // Media.playExplosionSound();

        this.isTriggered = true;
    }
    
    /**
     * @return
     */
    public Sprite getSprite() {
        return this.sprite;
    }

    /**
     * @param explosionRange
     *            to set
     */
    public void setExplosionRange(short explosionRange) {
        this.explosionRange = explosionRange;
    }

    /**
     * @return explosionRange
     */
    public int getExplosionRange() {
        return explosionRange;
    }

    /**
     * override
     * 
     * @see de.enough.polish.io.Externalizable#read(java.io.DataInputStream)
     */
    public void read(DataInputStream in) throws IOException {
        // TODO Auto-generated method stub

    }

    /**
     * override
     * 
     * @see de.enough.polish.io.Externalizable#write(java.io.DataOutputStream)
     */
    public void write(DataOutputStream out) throws IOException {
        // TODO Auto-generated method stub

    }

}
